#include "usart.h"

uint16_t VOICE_STATUS = 1; // 语音播放状态

struct GPS_RecvData GPSRecvData; // 创建结构体变量RecvData

// 接受状态
uint16_t USART1_RX_STA = 0;			   // 接受状态标记
uint8_t USART1_RX_BUF[USARTx_REC_LEN]; // 接受缓冲区，最大为USARTx_REC_LEN个字节

// 接受状态
uint16_t USART2_RX_STA = 0;							// 接受状态标记
uint8_t ShortMessageRecvBuf_usart2[USARTx_REC_LEN]; // 接受缓冲区，最大为USARTx_REC_LEN个字节

// 接受状态
uint16_t USART3_RX_STA = 0;					 // 接受状态标记
uint8_t VoiceRecvBuf_usart3[USARTx_REC_LEN]; // 接受缓冲区，最大为USARTx_REC_LEN个字节

// 作用:用来串口调试的
//  重定向C库函数printf到串口，重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
	USART_SendData(USART1, (uint8_t)ch);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
		;

	return (ch);
}

/*
作用:通过DMA1_CH7发送数据到USART2
参数: data: 要发送的数据 , len,发送数据长度
*/
void USART2_DMA_SendString(const char *data)
{
	// 获取消息长度
	u8 len = strlen(data);

	// 确保要发送的数据大小不超过缓冲区大小
	if (len > LEN_DMA_SEND_BUF)
	{
		len = LEN_DMA_SEND_BUF;
	}

	// 配置USART2的DMA发送方式
	USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);

	// 设置DMA传输的数据长度
	DMA_SetCurrDataCounter(DMA1_Channel7, len);

	// 将数据填充到DMA缓冲区
	memset(dma1_ch7_send_buf, 0, LEN_DMA_SEND_BUF); // 清空DMA缓冲区
	memcpy(dma1_ch7_send_buf, data, len);

	// 启用DMA传输通道
	DMA_Cmd(DMA1_Channel7, ENABLE);
	

	// 等待DMA传输完成
	while (DMA_GetFlagStatus(DMA1_FLAG_TC7) == RESET)
		;

	// 清除DMA传输完成标志位
	DMA_ClearFlag(DMA1_FLAG_TC7);

	// 禁用DMA传输通道
	DMA_Cmd(DMA1_Channel7, DISABLE);
}

/*
目的:给语音模块发送GBK格式的字符串
作用:通过DMA_CH2发送数据到USART3
参数: data: 要发送的数据 , len,发送数据长度
*/
void SendVoiceMessages(char *data)
{
	uint8_t len = strlen(data);

	// 判断语音播报是否正在进行		播放时为0,空闲时为1
	if (VOICE_STATUS)
	{
		// 确保要发送的数据大小不超过缓冲区大小
		if (len > LEN_DMA_SEND_BUF)
		{
			len = LEN_DMA_SEND_BUF;
		}

		// 配置USART3的DMA发送方式
		USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);

		// 设置DMA传输的数据长度
		DMA_SetCurrDataCounter(DMA1_Channel2, len);

		// 将数据填充到DMA缓冲区
		memset(dma1_ch2_send_buf, 0, LEN_DMA_SEND_BUF); // 清空DMA缓冲区
		memcpy(dma1_ch2_send_buf, data, len);

		// 启用DMA传输通道
		DMA_Cmd(DMA1_Channel2, ENABLE);

		// 等待DMA传输完成
		while (DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET)
			;

		// 清除DMA传输完成标志位
		DMA_ClearFlag(DMA1_FLAG_TC2);

		// 禁用DMA传输通道USART1初始化
		DMA_Cmd(DMA1_Channel2, DISABLE);
	}
}

/*
USART1初始化
TX1 PA.9
RX1 PA.10
*/
void USART1_Init(u32 bound)
{
	// GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	// 使能GPIOA时钟和USART1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

	// USART1_TX  GPIOA.9
	GPIO_InitStructure.GPIO_Pin = USART1_TX_PIN; // PA9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
	GPIO_Init(USART1_TX_PORT, &GPIO_InitStructure); // 初始化GPIOA.9

	// USART1_RX  GPIOA.10
	GPIO_InitStructure.GPIO_Pin = USART1_RX_PIN;		  // PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
	GPIO_Init(USART1_RX_PORT, &GPIO_InitStructure);		  // 初始化GPIOA.10

	// USART1 初始化设置
	USART_InitStructure.USART_BaudRate = bound;										// 串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						// 字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;							// 一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;								// 无奇偶校验
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					// 收发模式
	USART_Init(USART1, &USART_InitStructure);										// 初始化串口1

	// USART1 NVIC配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;		  // 子优先级4
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			  // IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);							  // 根据指定的参数初始化VIC寄存器

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 开启串口接收中断
	USART_Cmd(USART1, ENABLE);					   // 使能串口1
}

/*
USART2初始化
TX2 PA.2
RX2 PA.3
*/
void USART2_Init(u32 bound)
{
	// GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	// 使能GPIOA时钟和USART1时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	// USART2_TX  GPIOA.2
	GPIO_InitStructure.GPIO_Pin = USART2_TX_PIN; // PA.2
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
	GPIO_Init(USART2_TX_PORT, &GPIO_InitStructure); // 初始化GPIOA.2

	// USART2_RX  GPIOA.3
	GPIO_InitStructure.GPIO_Pin = USART2_RX_PIN;		  // PA.3
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
	GPIO_Init(USART2_RX_PORT, &GPIO_InitStructure);		  // 初始化GPIOA.10

	// USART2 初始化设置
	USART_InitStructure.USART_BaudRate = bound;										// 串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						// 字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;							// 一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;								// 无奇偶校验
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					// 收发模式
	USART_Init(USART2, &USART_InitStructure);										// 初始化串口2

	// USART1 NVIC配置
	NVIC_InitStructure.NVIC_IRQChannel = USART2_NVIC_IRQChannel;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		  // 子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			  // IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);							  // 根据指定的参数初始化VIC寄存器

	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 开启串口接收中断

	USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); // 使能串口2的DMA发送
	USART2_Tx_DMA1_CH7_Init();					   // 初始化USART2_Tx DMA1_CH7
	USART_Cmd(USART2, ENABLE);					   // 使能串口2
}

/*
USART3初始化	语音模块
TX3 PB.10
RX3	PB.11
*/
void USART3_Init(u32 bound)
{
	// GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	// 使能USART3  GPIOB GPIOC
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	USART_DeInit(USART3); // 复位串口3

	// PB.10 USART3_Tx
	GPIO_InitStructure.GPIO_Pin = USART3_TX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(USART3_TX_PORT, &GPIO_InitStructure);

	// PB.11 USART3_Rx
	GPIO_InitStructure.GPIO_Pin = USART3_RX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(USART3_RX_PORT, &GPIO_InitStructure);

	// USART3 初始化设置
	USART_InitStructure.USART_BaudRate = bound;										// 串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						// 字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;							// 一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;								// 无奇偶校验
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;					// 收发模式
	USART_Init(USART3, &USART_InitStructure);										// 初始化串口3

	// USART3 NVIC配置
	NVIC_InitStructure.NVIC_IRQChannel = USART3_NVIC_IRQChannel;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		  // 子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			  // IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);							  // 根据指定的参数初始化VIC寄存器

	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 开启串口接收中断

	USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE); // 使能串口3的DMA发送
	USART3_Tx_DMA1_CH2_Init();					   // 初始化USART3_Tx DMA1_CH2
	USART_Cmd(USART3, ENABLE);					   // 使能串口3
}

/*	串口1中断服务函数	*/
void USART1_IRQHandler(void)
{
	uint8_t Res = 0; // 接收到的数据

	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // 判断USART1的接收中断标志位是否被置位
	{
		Res = USART_ReceiveData(USART1); // 读取接受到的数据

		if (USART1_RX_STA < USARTx_REC_LEN) // 还可以接受数据
		{
			if (Res == '$')
			{
				USART1_RX_STA = 0; // 遇到$接受下标置为零
			}

			USART1_RX_BUF[USART1_RX_STA++] = Res;											   // 记录接受到值
			if (USART1_RX_BUF[0] == '$' && USART1_RX_BUF[4] == 'L' && USART1_RX_BUF[5] == 'L') // 确定是否收到"GPRMC"这一帧数据
			{
				if (Res == '\n')
				{
					memset(GPSRecvData.GPS_Buffer, 0, GPS_Buffer_Length);		  // 先将GPS接受缓冲区清空
					memcpy(GPSRecvData.GPS_Buffer, USART1_RX_BUF, USART1_RX_STA); // 保存$GPRMC这一帧数据
					USART1_RX_STA = 0;
					memset(USART1_RX_BUF, 0, USARTx_REC_LEN); // 清空接收缓冲区
				}
			}
		}
		else
		{
			USART1_RX_STA = 0; // 重置接收状态

			memset(USART1_RX_BUF, 0, USARTx_REC_LEN); // 清空接收缓冲区
		}

		// 清除接收中断标志位
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

/*	串口2中断服务函数	*/
void USART2_IRQHandler(void)
{
	uint8_t Res; // 接收到的数据

	if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // 判断USART2的接收中断标志位是否被置位
	{
		Res = USART_ReceiveData(USART2); // 读取接受到的数据

		if (USART2_RX_STA < USARTx_REC_LEN) // 还可以接受数据
		{
			ShortMessageRecvBuf_usart2[USART2_RX_STA++] = Res; // 记录接受到值
		}
		else
		{
			USART2_RX_STA = 0; // 重置接收状态

			memset(ShortMessageRecvBuf_usart2, 0, USARTx_REC_LEN); // 清空接收缓冲区
		}

		// 清除接收中断标志位
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
	}
}

/*	串口3中断服务函数	*/
void USART3_IRQHandler(void)
{
	uint8_t Res; // 接收到的数据

	if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) // 判断USART3的接收中断标志位是否被置位
	{
		Res = USART_ReceiveData(USART3);	// 读取接受到的数据
		if (USART3_RX_STA < USARTx_REC_LEN) // 还可以接受数据
		{
			if (Res == 0x41) //	0x41(A):播报开始标志
			{
				VOICE_STATUS = !VOICE_STATUS;
			}
			if (Res == 0x4F) // 0x4F(O):播报结束标志
			{
				VOICE_STATUS = !VOICE_STATUS;
			}

			VoiceRecvBuf_usart3[USART3_RX_STA++] = Res; // 记录接受到值
		}
		else
		{
			USART3_RX_STA = 0; // 重置接收状态

			memset(VoiceRecvBuf_usart3, 0, USARTx_REC_LEN); // 清空接收缓冲区
		}
		// 清除接收中断标志位
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
	}
}
